home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 1.iso / toolbox / src / exampleCode / opengl / xlib / tesstest.c < prev    next >
C/C++ Source or Header  |  1996-11-11  |  23KB  |  810 lines

  1. /*
  2.  * (c) Copyright 1994, Silicon Graphics, Inc.
  3.  * ALL RIGHTS RESERVED
  4.  *
  5.  * Permission to use, copy, modify, and distribute this software for
  6.  * any purpose and without fee is hereby granted, provided that the above
  7.  * copyright notice appear in all copies and that both the copyright notice
  8.  * and this permission notice appear in supporting documentation, and that
  9.  * the name of Silicon Graphics, Inc. not be used in advertising
  10.  * or publicity pertaining to distribution of the software without specific,
  11.  * written prior permission.
  12.  *
  13.  * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
  14.  * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
  15.  * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
  16.  * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
  17.  * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
  18.  * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
  19.  * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
  20.  * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
  21.  * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
  22.  * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
  23.  * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
  24.  * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
  25.  *
  26.  * U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
  27.  * Use, duplication, or disclosure by the Government is subject to
  28.  * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
  29.  * (c)(1)(ii) of the Rights in Technical Data and Computer Software
  30.  * clause at DFARS 252.227-7013 and/or in similar or successor
  31.  * clauses in the FAR or the DOD or NASA FAR Supplement.
  32.  * Unpublished-- rights reserved under the copyright laws of the
  33.  * United States.  Contractor/manufacturer is Silicon Graphics,
  34.  * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
  35.  *
  36.  * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
  37.  */
  38. #include <GL/glx.h>
  39. #include <GL/glu.h>
  40. #include <stdio.h>
  41. #include <string.h>
  42. #include <unistd.h>
  43. #include <stdlib.h>
  44. #include <X11/keysym.h>
  45. #include <malloc.h>
  46. #include <assert.h>
  47.  
  48. static int RGB_SB_attributes[] = {
  49.     GLX_RGBA,
  50.     GLX_RED_SIZE, 1,
  51.     GLX_GREEN_SIZE, 1,
  52.     GLX_BLUE_SIZE, 1,
  53.     None,
  54. };
  55.  
  56. static int RGB_DB_attributes[] = {
  57.     GLX_RGBA,
  58.     GLX_RED_SIZE, 1,
  59.     GLX_GREEN_SIZE, 1,
  60.     GLX_BLUE_SIZE, 1,
  61.     GLX_DOUBLEBUFFER,
  62.     GLX_DEPTH_SIZE, 1,
  63.     GLX_STENCIL_SIZE, 1,
  64.     None,
  65. };
  66.  
  67. static int CI_SB_attributes[] = {
  68.     GLX_DEPTH_SIZE, 1,
  69.     GLX_STENCIL_SIZE, 1,
  70.     None,
  71. };
  72.  
  73. static int CI_DB_attributes[] = {
  74.     GLX_DOUBLEBUFFER,
  75.     GLX_DEPTH_SIZE, 1,
  76.     GLX_STENCIL_SIZE, 1,
  77.     None,
  78. };
  79.  
  80. int rgb = 1;
  81. int W = 500;
  82. int H = 500;
  83.  
  84. /*
  85. ** A contour.
  86. */
  87. struct vert {
  88.     GLdouble v[3];
  89.     struct vert *next;
  90. };
  91.  
  92. /*
  93. ** A polygon (multiple contours).
  94. */
  95. struct polygon {
  96.     struct vert *contour;
  97.     struct polygon *next;
  98. };
  99.  
  100. #define SELECT_LINE    1
  101. #define SELECT_VERTEX    2
  102.  
  103. struct polygon *thePoly = NULL;
  104. struct vert *foundVertex = NULL;
  105. int leftDown, middleDown, rightDown;
  106. int tessIt;
  107. int showTess;
  108. int doEdgeFlags;
  109. int gotError;
  110. int doubleBuf = 1;
  111. GLUtriangulatorObj *tobj;
  112. Display *dpy;
  113. Window window;
  114. Colormap cmap;
  115.  
  116. unsigned char font6x10[] = {
  117. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  118. 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x38, 0x38, 0x10, 0x00, 
  119. 0x00, 0x00, 0x54, 0x28, 0x54, 0x28, 0x54, 0x28, 0x54, 0x00, 
  120. 0x08, 0x08, 0x08, 0x3c, 0x48, 0x48, 0x78, 0x48, 0x48, 0x00, 
  121. 0x10, 0x10, 0x18, 0x10, 0x5c, 0x40, 0x60, 0x40, 0x70, 0x00, 
  122. 0x24, 0x24, 0x38, 0x24, 0x38, 0x38, 0x40, 0x40, 0x38, 0x00, 
  123. 0x20, 0x20, 0x38, 0x20, 0x3c, 0x78, 0x40, 0x40, 0x40, 0x00, 
  124. 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x28, 0x28, 0x38, 0x00, 
  125. 0x00, 0x00, 0x7c, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 
  126. 0x3c, 0x20, 0x20, 0x20, 0x48, 0x58, 0x68, 0x68, 0x48, 0x00, 
  127. 0x08, 0x08, 0x08, 0x08, 0x3c, 0x20, 0x30, 0x48, 0x48, 0x00, 
  128. 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x10, 0x10, 0x10, 0x10, 
  129. 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x00, 0x00, 0x00, 0x00, 
  130. 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x00, 0x00, 0x00, 0x00, 
  131. 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x10, 0x10, 0x10, 0x10, 
  132. 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x10, 0x10, 
  133. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 
  134. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 
  135. 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 
  136. 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  137. 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  138. 0x10, 0x10, 0x10, 0x10, 0x10, 0x1c, 0x10, 0x10, 0x10, 0x10, 
  139. 0x10, 0x10, 0x10, 0x10, 0x10, 0x70, 0x10, 0x10, 0x10, 0x10, 
  140. 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x10, 0x10, 0x10, 0x10, 
  141. 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 0x00, 0x00, 0x00, 
  142. 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 
  143. 0x00, 0x7c, 0x04, 0x08, 0x20, 0x40, 0x20, 0x08, 0x04, 0x00, 
  144. 0x00, 0x7c, 0x40, 0x20, 0x08, 0x04, 0x08, 0x20, 0x40, 0x00, 
  145. 0x00, 0x00, 0x28, 0x28, 0x28, 0x28, 0x7c, 0x00, 0x00, 0x00, 
  146. 0x00, 0x00, 0x40, 0x20, 0x7c, 0x10, 0x7c, 0x08, 0x04, 0x00, 
  147. 0x00, 0x20, 0x6c, 0x38, 0x20, 0x78, 0x20, 0x24, 0x18, 0x00, 
  148. 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 
  149. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  150. 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 
  151. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0x00, 
  152. 0x00, 0x00, 0x28, 0x28, 0x7c, 0x28, 0x7c, 0x28, 0x28, 0x00, 
  153. 0x00, 0x00, 0x10, 0x38, 0x14, 0x38, 0x50, 0x38, 0x10, 0x00, 
  154. 0x00, 0x00, 0x48, 0x54, 0x28, 0x10, 0x28, 0x54, 0x24, 0x00, 
  155. 0x00, 0x00, 0x34, 0x48, 0x54, 0x20, 0x50, 0x50, 0x20, 0x00, 
  156. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x10, 0x18, 0x00, 
  157. 0x00, 0x00, 0x08, 0x10, 0x20, 0x20, 0x20, 0x10, 0x08, 0x00, 
  158. 0x00, 0x00, 0x20, 0x10, 0x08, 0x08, 0x08, 0x10, 0x20, 0x00, 
  159. 0x00, 0x00, 0x00, 0x44, 0x28, 0x7c, 0x28, 0x44, 0x00, 0x00, 
  160. 0x00, 0x00, 0x00, 0x10, 0x10, 0x7c, 0x10, 0x10, 0x00, 0x00, 
  161. 0x00, 0x20, 0x10, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  162. 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 
  163. 0x00, 0x10, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  164. 0x00, 0x00, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x04, 0x00, 
  165. 0x00, 0x00, 0x10, 0x28, 0x44, 0x44, 0x44, 0x28, 0x10, 0x00, 
  166. 0x00, 0x00, 0x7c, 0x10, 0x10, 0x10, 0x50, 0x30, 0x10, 0x00, 
  167. 0x00, 0x00, 0x7c, 0x40, 0x20, 0x18, 0x04, 0x44, 0x38, 0x00, 
  168. 0x00, 0x00, 0x38, 0x44, 0x04, 0x18, 0x08, 0x04, 0x7c, 0x00, 
  169. 0x00, 0x00, 0x08, 0x08, 0x7c, 0x48, 0x28, 0x18, 0x08, 0x00, 
  170. 0x00, 0x00, 0x38, 0x44, 0x04, 0x64, 0x58, 0x40, 0x7c, 0x00, 
  171. 0x00, 0x00, 0x38, 0x44, 0x64, 0x58, 0x40, 0x20, 0x18, 0x00, 
  172. 0x00, 0x00, 0x20, 0x20, 0x10, 0x08, 0x08, 0x04, 0x7c, 0x00, 
  173. 0x00, 0x00, 0x38, 0x44, 0x44, 0x38, 0x44, 0x44, 0x38, 0x00, 
  174. 0x00, 0x00, 0x30, 0x08, 0x04, 0x34, 0x4c, 0x44, 0x38, 0x00, 
  175. 0x00, 0x10, 0x38, 0x10, 0x00, 0x10, 0x38, 0x10, 0x00, 0x00, 
  176. 0x00, 0x20, 0x10, 0x18, 0x00, 0x10, 0x38, 0x10, 0x00, 0x00, 
  177. 0x00, 0x00, 0x04, 0x08, 0x10, 0x20, 0x10, 0x08, 0x04, 0x00, 
  178. 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x7c, 0x00, 0x00, 0x00, 
  179. 0x00, 0x00, 0x40, 0x20, 0x10, 0x08, 0x10, 0x20, 0x40, 0x00, 
  180. 0x00, 0x00, 0x10, 0x00, 0x10, 0x10, 0x08, 0x44, 0x38, 0x00, 
  181. 0x00, 0x00, 0x38, 0x40, 0x58, 0x54, 0x4c, 0x44, 0x38, 0x00, 
  182. 0x00, 0x00, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x28, 0x10, 0x00, 
  183. 0x00, 0x00, 0x78, 0x24, 0x24, 0x38, 0x24, 0x24, 0x78, 0x00, 
  184. 0x00, 0x00, 0x38, 0x44, 0x40, 0x40, 0x40, 0x44, 0x38, 0x00, 
  185. 0x00, 0x00, 0x78, 0x24, 0x24, 0x24, 0x24, 0x24, 0x78, 0x00, 
  186. 0x00, 0x00, 0x7c, 0x40, 0x40, 0x78, 0x40, 0x40, 0x7c, 0x00, 
  187. 0x00, 0x00, 0x40, 0x40, 0x40, 0x78, 0x40, 0x40, 0x7c, 0x00, 
  188. 0x00, 0x00, 0x38, 0x44, 0x4c, 0x40, 0x40, 0x44, 0x38, 0x00, 
  189. 0x00, 0x00, 0x44, 0x44, 0x44, 0x7c, 0x44, 0x44, 0x44, 0x00, 
  190. 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x38, 0x00, 
  191. 0x00, 0x00, 0x38, 0x44, 0x04, 0x04, 0x04, 0x04, 0x1c, 0x00, 
  192. 0x00, 0x00, 0x44, 0x48, 0x50, 0x60, 0x50, 0x48, 0x44, 0x00, 
  193. 0x00, 0x00, 0x7c, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x00, 
  194. 0x00, 0x00, 0x44, 0x44, 0x44, 0x54, 0x6c, 0x44, 0x44, 0x00, 
  195. 0x00, 0x00, 0x44, 0x44, 0x4c, 0x54, 0x64, 0x44, 0x44, 0x00, 
  196. 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 
  197. 0x00, 0x00, 0x40, 0x40, 0x40, 0x78, 0x44, 0x44, 0x78, 0x00, 
  198. 0x00, 0x04, 0x38, 0x54, 0x44, 0x44, 0x44, 0x44, 0x38, 0x00, 
  199. 0x00, 0x00, 0x44, 0x48, 0x50, 0x78, 0x44, 0x44, 0x78, 0x00, 
  200. 0x00, 0x00, 0x38, 0x44, 0x04, 0x38, 0x40, 0x44, 0x38, 0x00, 
  201. 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x7c, 0x00, 
  202. 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x00, 
  203. 0x00, 0x00, 0x10, 0x28, 0x28, 0x28, 0x44, 0x44, 0x44, 0x00, 
  204. 0x00, 0x00, 0x44, 0x6c, 0x54, 0x54, 0x44, 0x44, 0x44, 0x00, 
  205. 0x00, 0x00, 0x44, 0x44, 0x28, 0x10, 0x28, 0x44, 0x44, 0x00, 
  206. 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x28, 0x44, 0x44, 0x00, 
  207. 0x00, 0x00, 0x7c, 0x40, 0x20, 0x10, 0x08, 0x04, 0x7c, 0x00, 
  208. 0x00, 0x00, 0x38, 0x20, 0x20, 0x20, 0x20, 0x20, 0x38, 0x00, 
  209. 0x00, 0x00, 0x04, 0x04, 0x08, 0x10, 0x20, 0x40, 0x40, 0x00, 
  210. 0x00, 0x00, 0x38, 0x08, 0x08, 0x08, 0x08, 0x08, 0x38, 0x00, 
  211. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x28, 0x10, 0x00, 
  212. 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  213. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10, 0x30, 0x00, 
  214. 0x00, 0x00, 0x3c, 0x44, 0x3c, 0x04, 0x38, 0x00, 0x00, 0x00, 
  215. 0x00, 0x00, 0x58, 0x64, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 
  216. 0x00, 0x00, 0x38, 0x44, 0x40, 0x44, 0x38, 0x00, 0x00, 0x00, 
  217. 0x00, 0x00, 0x34, 0x4c, 0x44, 0x4c, 0x34, 0x04, 0x04, 0x00, 
  218. 0x00, 0x00, 0x38, 0x40, 0x7c, 0x44, 0x38, 0x00, 0x00, 0x00, 
  219. 0x00, 0x00, 0x20, 0x20, 0x20, 0x78, 0x20, 0x24, 0x18, 0x00, 
  220. 0x38, 0x44, 0x38, 0x40, 0x30, 0x48, 0x34, 0x00, 0x00, 0x00, 
  221. 0x00, 0x00, 0x44, 0x44, 0x44, 0x64, 0x58, 0x40, 0x40, 0x00, 
  222. 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x30, 0x00, 0x10, 0x00, 
  223. 0x30, 0x48, 0x48, 0x08, 0x08, 0x08, 0x18, 0x00, 0x08, 0x00, 
  224. 0x00, 0x00, 0x44, 0x48, 0x70, 0x48, 0x44, 0x40, 0x40, 0x00, 
  225. 0x00, 0x00, 0x38, 0x10, 0x10, 0x10, 0x10, 0x10, 0x30, 0x00, 
  226. 0x00, 0x00, 0x44, 0x54, 0x54, 0x54, 0x68, 0x00, 0x00, 0x00, 
  227. 0x00, 0x00, 0x44, 0x44, 0x44, 0x64, 0x58, 0x00, 0x00, 0x00, 
  228. 0x00, 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, 0x00, 0x00, 0x00, 
  229. 0x40, 0x40, 0x40, 0x58, 0x64, 0x64, 0x58, 0x00, 0x00, 0x00, 
  230. 0x04, 0x04, 0x04, 0x34, 0x4c, 0x4c, 0x34, 0x00, 0x00, 0x00, 
  231. 0x00, 0x00, 0x40, 0x40, 0x40, 0x64, 0x58, 0x00, 0x00, 0x00, 
  232. 0x00, 0x00, 0x78, 0x04, 0x38, 0x40, 0x38, 0x00, 0x00, 0x00, 
  233. 0x00, 0x00, 0x18, 0x24, 0x20, 0x20, 0x78, 0x20, 0x20, 0x00, 
  234. 0x00, 0x00, 0x34, 0x4c, 0x44, 0x44, 0x44, 0x00, 0x00, 0x00, 
  235. 0x00, 0x00, 0x10, 0x28, 0x28, 0x44, 0x44, 0x00, 0x00, 0x00, 
  236. 0x00, 0x00, 0x28, 0x54, 0x54, 0x44, 0x44, 0x00, 0x00, 0x00, 
  237. 0x00, 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, 0x00, 0x00, 0x00, 
  238. 0x38, 0x44, 0x04, 0x34, 0x4c, 0x44, 0x44, 0x00, 0x00, 0x00, 
  239. 0x00, 0x00, 0x7c, 0x20, 0x10, 0x08, 0x7c, 0x00, 0x00, 0x00, 
  240. 0x00, 0x00, 0x0c, 0x10, 0x08, 0x30, 0x08, 0x10, 0x0c, 0x00, 
  241. 0x00, 0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 
  242. 0x00, 0x00, 0x60, 0x10, 0x20, 0x18, 0x20, 0x10, 0x60, 0x00, 
  243. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x54, 0x24, 0x00, 
  244. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
  245. };
  246.  
  247. int fontbase;
  248.  
  249. void initializeFont(void)
  250. {
  251.     int i;
  252.  
  253.     fontbase=glGenLists(256);
  254.     glPixelStorei(GL_UNPACK_LSB_FIRST, GL_FALSE);
  255.     glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  256.  
  257.     for (i=0; i<128; i++) {
  258.     glNewList(i+fontbase, GL_COMPILE);
  259.     glBitmap(6, 10, 0.0, 0.0, 6.0, 0.0, font6x10+10*i);
  260.     glEndList();
  261.     }
  262. }
  263.  
  264. void writeFont(char *string)
  265. {
  266.     glListBase(fontbase);
  267.     glCallLists(strlen(string), GL_BYTE, (unsigned char *) string);
  268. }
  269.  
  270. void myBegin(GLenum which)
  271. {
  272.     glBegin(which);
  273. }
  274.  
  275. void myEnd(void)
  276. {
  277.     glEnd();
  278. }
  279.  
  280. void tessPoly(void)
  281. {
  282.     struct polygon *poly;
  283.     struct vert *vert;
  284.  
  285.     gluBeginPolygon(tobj);
  286.     for (poly=thePoly; poly; poly=poly->next) {
  287.     gluNextContour(tobj, GLU_UNKNOWN);
  288.     for (vert=poly->contour; vert; vert=vert->next) {
  289.         gluTessVertex(tobj, vert->v, vert->v);
  290.     }
  291.     }
  292.     gluEndPolygon(tobj);
  293. }
  294.  
  295. static void Redraw(GLenum mode)
  296. {
  297.     struct polygon *poly;
  298.     struct vert *vert;
  299.  
  300.     glClear(GL_COLOR_BUFFER_BIT);
  301.     glPointSize(3);
  302.  
  303.     gotError = 0;
  304.     glInitNames();
  305.     if (tessIt) {
  306.     glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
  307.     glColor3f(0.5, 0.5, 0.5);
  308.     glIndexf(15);
  309.     tessPoly();
  310.     }
  311.     if (!gotError && showTess) {
  312.     glColor3f(1.0, 1.0, 0.0);
  313.     glIndexf(3);
  314.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  315.     tessPoly();
  316.     }
  317.     if (!gotError && doEdgeFlags) {
  318.     glLineWidth(3);
  319.     glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  320.     glColor3f(0.0, 0.0, 1.0);
  321.     glIndexf(4);
  322.     gluTessCallback(tobj, GLU_EDGE_FLAG, (void *) glEdgeFlag);
  323.     tessPoly();
  324.     gluTessCallback(tobj, GLU_EDGE_FLAG, NULL);
  325.     glLineWidth(1);
  326.     }
  327.  
  328.     if (gotError) {
  329.     glColor3f(1.0, 1.0, 1.0);
  330.     glIndexf(7);
  331.     glRasterPos2f(5.0, 15.0);
  332.     glColor3f(0.0, 0.0, 1.0);
  333.     glIndexf(4);
  334.     writeFont((char *) gluErrorString(gotError));
  335.     }
  336.  
  337.     /* So glLoadName will be legal -- strange semantics */
  338.     glPushName(1);
  339.     for (poly=thePoly; poly; poly=poly->next) {
  340.     glColor3f(0.0, 1.0, 0.0);
  341.     glIndexf(2);
  342.     glLoadName(SELECT_LINE);
  343.     for (vert=poly->contour; vert; vert=vert->next) {
  344.         glPushName((GLuint) vert);
  345.         glBegin(GL_LINES);
  346.         glVertex2dv(vert->v);
  347.         if (vert->next) {
  348.         glVertex2dv(vert->next->v);
  349.         } else {
  350.         glVertex2dv(poly->contour->v);
  351.         }
  352.         glEnd();
  353.         glPopName();
  354.     }
  355.     glColor3f(1.0, 0.0, 0.0);
  356.     glIndexf(1);
  357.     glLoadName(SELECT_VERTEX);
  358.     for (vert=poly->contour; vert; vert=vert->next) {
  359.         glPushName((GLuint) vert);
  360.         glBegin(GL_POINTS);
  361.         glVertex2dv(vert->v);
  362.         glEnd();
  363.         glPopName();
  364.     }
  365.     }
  366.  
  367.     if (mode == GL_RENDER) {
  368.     glXSwapBuffers(dpy, window);
  369.     }
  370. }
  371.  
  372. static void Usage(void)
  373. {
  374.     fprintf(stderr, "Usage: tesstest [-c] [-s]\n");
  375.     fprintf(stderr, " -c:  run in color index mode\n");
  376.     fprintf(stderr, " -s:  run in singlebuffer mode\n");
  377.     exit(1);
  378. }
  379.  
  380. static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
  381. {
  382.     if ((e->type == MapNotify) && (e->xmap.window == (Window) arg)) {
  383.     return GL_TRUE;
  384.     }
  385.     return GL_FALSE;
  386. }
  387.  
  388. /*
  389. ** Create a new contour at x,y.
  390. */
  391. void newContour(int x, int y)
  392. {
  393.     struct polygon *newPoly;
  394.     struct vert *newCont;
  395.     struct polygon **polyTail;
  396.  
  397.     newPoly = (struct polygon *) malloc(sizeof(struct polygon));
  398.     newCont = (struct vert *) malloc(sizeof(struct vert));
  399.  
  400.     polyTail = &thePoly;
  401.     while (*polyTail) {
  402.     polyTail = &((*polyTail)->next);
  403.     }
  404.  
  405.     *polyTail = newPoly;
  406.     newPoly->next = NULL;
  407.     newPoly->contour = newCont;
  408.  
  409.     newCont->next = NULL;
  410.     newCont->v[0] = x;
  411.     newCont->v[1] = y;
  412.     newCont->v[2] = 0;
  413. }
  414.  
  415. /*
  416. ** Create a new edge at this vertex
  417. */
  418. struct vert *addVertex(struct vert *where, int x, int y)
  419. {
  420.     struct vert *newVert;
  421.  
  422.     newVert = (struct vert *) malloc(sizeof(struct vert));
  423.  
  424.     newVert->next = where->next;
  425.     where->next = newVert;
  426.     newVert->v[0] = x;
  427.     newVert->v[1] = y;
  428.     newVert->v[2] = 0;
  429.  
  430.     return newVert;
  431. }
  432.  
  433. void deleteVertex(void)
  434. {
  435.     struct polygon *poly, *poly2;
  436.     struct vert *vert;
  437.  
  438.     if (!foundVertex) return;
  439.  
  440.     for (poly=thePoly; poly; poly=poly->next) {
  441.     if (poly->contour == foundVertex) {
  442.         poly->contour = foundVertex->next;
  443.         free(foundVertex);
  444.         foundVertex = NULL;
  445.         if (poly->contour == NULL) {
  446.         if (poly == thePoly) {
  447.             thePoly = poly->next;
  448.             free(poly);
  449.             return;
  450.         }
  451.         for (poly2=thePoly; poly2; poly2=poly2->next) {
  452.             if (poly2->next == poly) {
  453.             poly2->next = poly->next;
  454.             free(poly);
  455.             return;
  456.             }
  457.         }
  458.         }
  459.         return;
  460.     }
  461.     for (vert=poly->contour; vert; vert=vert->next) {
  462.         if (vert->next == foundVertex) {
  463.         vert->next = foundVertex->next;
  464.         free(foundVertex);
  465.         foundVertex = NULL;
  466.         return;
  467.         }
  468.     }
  469.     }
  470. }
  471.  
  472. void findVertex(int x, int y, int type)
  473. {
  474.     static GLuint selectBuf[1000];
  475.     GLint hits;
  476.     GLint viewport[4];
  477.     int i;
  478.  
  479.     foundVertex = NULL;
  480.     glSelectBuffer(1000, selectBuf);
  481.     (void) glRenderMode(GL_SELECT);
  482.     glInitNames();
  483.  
  484.     glMatrixMode(GL_PROJECTION);
  485.     glPushMatrix();
  486.     glLoadIdentity();
  487.     glGetIntegerv(GL_VIEWPORT, viewport);
  488.     gluPickMatrix(x, y, 6, 6, viewport);
  489.     gluOrtho2D(0,W,0,H);
  490.     glMatrixMode(GL_MODELVIEW);
  491.  
  492.     Redraw(GL_SELECT);
  493.  
  494.     glMatrixMode(GL_PROJECTION);
  495.     glPopMatrix();
  496.  
  497.     hits = glRenderMode(GL_RENDER);
  498.     if (hits <= 0) return;
  499.  
  500.     /*
  501.     ** Each entry looks like:
  502.     **   count (2)
  503.     **   min z, max z
  504.     **   SELECT_LINE or SELECT_VERTEX
  505.     **   pointer to vertex.
  506.     */
  507.  
  508.     i = 0;
  509.     while (hits) {
  510.     hits --;
  511.     if (selectBuf[i] == 0) {
  512.         i+= 3;
  513.         continue;
  514.     }
  515.     assert(selectBuf[i] == 2);
  516.     i += 3;
  517.     if (selectBuf[i] == type) {
  518.         foundVertex = (struct vert *) selectBuf[i+1];
  519.         return;
  520.     }
  521.     i += 2;
  522.     }
  523. }
  524.  
  525. void moveVertex(int x, int y)
  526. {
  527.     if (foundVertex) {
  528.     foundVertex->v[0] = x;
  529.     foundVertex->v[1] = y;
  530.     }
  531. }
  532.  
  533. void errorHandler(GLenum error)
  534. {
  535.     if (gotError) {
  536.     printf("Double errors!?!\n");
  537.     }
  538.     gotError = error;
  539. }
  540.  
  541. static void Init(void)
  542. {
  543.     glViewport(0,0,W,H);
  544.     glMatrixMode(GL_PROJECTION);
  545.     glLoadIdentity();
  546.     gluOrtho2D(0,W,0,H);
  547.     glMatrixMode(GL_MODELVIEW);
  548.  
  549.     if (rgb) {
  550.     glClearColor(0,0,0,0);
  551.     } else {
  552.     glClearIndex(0);
  553.     }
  554.  
  555.     glClear(GL_COLOR_BUFFER_BIT);
  556.  
  557.     tobj = gluNewTess();
  558.     gluTessCallback(tobj, GLU_VERTEX, glVertex2dv);
  559.     gluTessCallback(tobj, GLU_BEGIN, myBegin);
  560.     gluTessCallback(tobj, GLU_END, myEnd);
  561.     gluTessCallback(tobj, GLU_ERROR, errorHandler);
  562.  
  563.     initializeFont();
  564. }
  565.  
  566. static void setColorMap(void)
  567. {
  568.     XColor *xc;
  569.     long i;
  570.  
  571.     xc = (XColor *) malloc(16 * sizeof(XColor));
  572.     for (i=0; i<16; i++) {
  573.     xc[i].pixel = i;
  574.     xc[i].red = (i & 1) ? 65535 : 0;
  575.     xc[i].green = (i & 2) ? 65535 : 0;
  576.     xc[i].blue = (i & 4) ? 65535 : 0;
  577.     if (i > 8) {
  578.         xc[i].red /= 2;
  579.         xc[i].green /= 2;
  580.         xc[i].blue /= 2;
  581.     }
  582.     xc[i].flags = DoRed | DoGreen | DoBlue;
  583.     }
  584.     XStoreColors(dpy, cmap, xc, 16);
  585.  
  586.     free((void *) xc);
  587. }
  588.  
  589. int main(int argc, char** argv)
  590. {
  591.     XVisualInfo *vi;
  592.     XSetWindowAttributes swa;
  593.     GLXContext cx;
  594.     XEvent event;
  595.     GLboolean needDisplay;
  596.     XColor white;
  597.     int i;
  598.  
  599.     rgb = 1;
  600.     for (i = 1; i < argc; i++) {
  601.         if (argv[i][0] == '-') {
  602.             switch (argv[i][1]) {
  603.               case 'c':
  604.                 rgb = GL_FALSE;
  605.                 break;
  606.           case 's':
  607.         doubleBuf = 0;
  608.         break;
  609.               default:
  610.                 Usage();
  611.             }
  612.         } else {
  613.             Usage();
  614.         }
  615.     }
  616.  
  617.     dpy = XOpenDisplay(0);
  618.     if (!dpy) {
  619.     fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
  620.     return -1;
  621.     }
  622.  
  623.     vi = glXChooseVisual(dpy, DefaultScreen(dpy),
  624.         doubleBuf ? (rgb ? RGB_DB_attributes : CI_DB_attributes) :
  625.         (rgb ? RGB_SB_attributes : CI_SB_attributes));
  626.     if (!vi) {
  627.     fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
  628.         getenv("DISPLAY"));
  629.     return -1;
  630.     }
  631.  
  632.     cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
  633.                rgb ? AllocNone : AllocAll);
  634.     white.red = ~0;
  635.     white.green = ~0;
  636.     white.blue = ~0;
  637.     XAllocColor(dpy, cmap, &white);
  638.  
  639.     swa.border_pixel = 0;
  640.     swa.background_pixel = white.pixel;
  641.     swa.colormap = cmap;
  642.     swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
  643.     | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask |
  644.     PointerMotionMask;
  645.     window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 10, 10,
  646.                W, H,
  647.                0, vi->depth, InputOutput, vi->visual,
  648.                CWBackPixel|CWBorderPixel|CWColormap|CWEventMask,
  649.                &swa);
  650.     XSetWMColormapWindows(dpy, window, &window, 1);
  651.     XMapWindow(dpy, window);
  652.     XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
  653.  
  654.     cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
  655.     if (!glXMakeCurrent(dpy, window, cx)) {
  656.     fprintf(stderr, "Can't make window current to context\n");
  657.     return -1;
  658.     }
  659.  
  660.     if (!rgb) {
  661.     setColorMap();
  662.     }
  663.  
  664.     Init();
  665.  
  666.     printf("\n\nc to create a new contour.\n");
  667.     printf("d to delete a vertex.\n");
  668.     printf("t to tessellate and draw the polygon.\n");
  669.     printf("s to show the tessellation.\n");
  670.     printf("e to draw the polygon in Polymode(GL_LINE) with edge flags.\n");
  671.     printf("Left mouse moves a vertex.\n");
  672.     printf("Middle mouse inserts a vertex into a contour.\n");
  673.  
  674.     needDisplay = GL_TRUE;
  675.     leftDown = middleDown = rightDown = GL_FALSE;
  676.     newContour(100, 100);
  677.     findVertex(100, 100, SELECT_VERTEX);
  678.     addVertex(foundVertex, 100, 400);
  679.     findVertex(100, 400, SELECT_VERTEX);
  680.     addVertex(foundVertex, 400, 400);
  681.     findVertex(400, 400, SELECT_VERTEX);
  682.     addVertex(foundVertex, 400, 100);
  683.     foundVertex = NULL;
  684.     for (;;) {
  685.     do {
  686.         GLboolean setNeed;
  687.  
  688.         XNextEvent(dpy, &event);
  689.         setNeed = GL_TRUE;
  690.         switch (event.type) {
  691.           case Expose:
  692.         break;
  693.           case ConfigureNotify:
  694.         W = event.xconfigure.width;
  695.         H = event.xconfigure.height;
  696.         glViewport(0,0,W,H);
  697.         glMatrixMode(GL_PROJECTION);
  698.         glLoadIdentity();
  699.         gluOrtho2D(0,W,0,H);
  700.         glMatrixMode(GL_MODELVIEW);
  701.         break;
  702.           case ButtonPress:
  703.         /* 
  704.         ** Only effectively allow one mouse button down at a time.
  705.         */
  706.         setNeed = GL_FALSE;
  707.         leftDown = middleDown = rightDown = GL_FALSE;
  708.         switch(event.xbutton.button) {
  709.           case 1:    /* Left - move vertex */
  710.             findVertex(event.xbutton.x, H - event.xbutton.y, 
  711.                 SELECT_VERTEX);
  712.             moveVertex(event.xbutton.x, H - event.xbutton.y);
  713.             leftDown = GL_TRUE;
  714.             break;
  715.           case 2:    /* Middle - insert vertex */
  716.             middleDown = GL_TRUE;
  717.             findVertex(event.xbutton.x, H - event.xbutton.y, 
  718.                 SELECT_LINE);
  719.             if (foundVertex) {
  720.             foundVertex = addVertex(foundVertex, 
  721.                 event.xbutton.x, H - event.xbutton.y);
  722.             }
  723.             break;
  724.           case 3:    /* Right */
  725.             rightDown = GL_TRUE;
  726.             break;
  727.         }
  728.         break;
  729.           case ButtonRelease:
  730.         setNeed = GL_FALSE;
  731.         switch(event.xbutton.button) {
  732.           case 1:
  733.             if (leftDown && foundVertex) {
  734.             moveVertex(event.xbutton.x, H - event.xbutton.y);
  735.             leftDown = GL_FALSE;
  736.             setNeed = GL_TRUE;
  737.             } 
  738.             break;
  739.           case 2:
  740.             if (middleDown && foundVertex) {
  741.             moveVertex(event.xbutton.x, H - event.xbutton.y);
  742.             middleDown = GL_FALSE;
  743.             setNeed = GL_TRUE;
  744.             }
  745.             break;
  746.           case 3:
  747.             rightDown = GL_FALSE;
  748.             break;
  749.         }
  750.         break;
  751.           case MotionNotify:
  752.         if (leftDown && foundVertex) {
  753.             moveVertex(event.xmotion.x, H - event.xmotion.y);
  754.         } else if (middleDown && foundVertex) {
  755.             moveVertex(event.xmotion.x, H - event.xmotion.y);
  756.         } else {
  757.             setNeed = GL_FALSE;
  758.         }
  759.         break;
  760.           case KeyPress:
  761.         {
  762.             char buf[100];
  763.             int rv;
  764.             KeySym ks;
  765.  
  766.             rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
  767.             switch (ks) {
  768.               case XK_C: case XK_c:
  769.             newContour(event.xkey.x, H - event.xkey.y);
  770.             break;
  771.               case XK_D: case XK_d:
  772.             findVertex(event.xbutton.x, H - event.xbutton.y, 
  773.                 SELECT_VERTEX);
  774.             if (foundVertex) {
  775.                 deleteVertex();
  776.             } else setNeed = GL_FALSE;
  777.             break;
  778.               case XK_T: case XK_t:
  779.             tessIt = 1-tessIt;
  780.             break;
  781.               case XK_S: case XK_s:
  782.             showTess = 1-showTess;
  783.             break;
  784.               case XK_E: case XK_e:
  785.             doEdgeFlags = 1-doEdgeFlags;
  786.             break;
  787.               case XK_Escape:
  788.             return 0;
  789.               default:
  790.             setNeed = GL_FALSE;
  791.             break;
  792.             }
  793.         }
  794.         break;
  795.           default:
  796.         setNeed = GL_FALSE;
  797.         break;
  798.         }
  799.         if (setNeed) needDisplay = GL_TRUE;
  800.     } while (XPending(dpy) != 0);
  801.  
  802.     if (needDisplay) {
  803.         needDisplay = GL_FALSE;
  804.         Redraw(GL_RENDER);
  805.     }
  806.     }
  807. }
  808.  
  809.  
  810.